#include "stdafx.h"

extern WSASetLastError_proxy_t pTrueWSASetLastError;

SOCKET socket_proxy (
    __in  int af,
    __in  int type,
    __in  int protocol
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "socket");
        socket_in_inout socketIN(af, type, protocol);
        
        std::vector<char> out_buffer;
        Serialize(header, socketIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        socket_out_inout socketOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(socketOUT);

        if(socketOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(socketOUT.wsa_last_error_);
            return INVALID_SOCKET;
        }
        return socketOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "socket: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    return INVALID_SOCKET;
}

SOCKET WSASocket_proxy (
    __in  int                af,
    __in  int                type,
    __in  int                protocol,
    __in  LPWSAPROTOCOL_INFO lpProtocolInfo,
    __in  GROUP              g,
    __in  DWORD              dwFlags
    )
{
    try
    {
    //SEND
        Header header(GetCurrentThreadId(), "WSASocket");
        WSASocket_in_inout WSASocketIN(af, type, protocol,
                                       lpProtocolInfo, g, dwFlags);
        
        std::vector<char> out_buffer;
        Serialize(header, WSASocketIN, out_buffer);

        SendToClient (out_buffer);
        
    //RECEIVE()
        WSASocket_out_inout WSASocketOUT;

        std::vector<char> in_buffer;
        
        RecvFromClient (in_buffer, header);
        Deserialize deserialize(in_buffer);
        deserialize(WSASocketOUT);

        if(WSASocketOUT.wsa_last_error_ != 0)
        {
            pTrueWSASetLastError(WSASocketOUT.wsa_last_error_);
            return INVALID_SOCKET;
        }
        return WSASocketOUT.ret_;
    }
    catch (std::exception& ex)
    {
        LOG(plog::error) << "WSASocket: " << ex.what();
    }
    pTrueWSASetLastError (WSAEWOULDBLOCK);
    return INVALID_SOCKET;
}
